<template>
	<div class="delay-section">
		<div class="section-header">
			<h2>{{ title }}</h2>
			<div class="category-name">{{ categoryName }}</div>
			<div class="section-count">{{ items?.length || 0 }}项延期</div>
		</div>
		<div class="category-content">
			<div class="scroll-container" ref="scrollContainerRef">
				<div class="scroll-content" ref="scrollContentRef">
					<!-- 数据行 -->
					<div v-for="(item, index) in items || []" :key="`${type}-${index}`" class="delay-item" :class="[getDelayClass(item.delay), { 'first-item': index === 0 && shouldShowScrollIndicator }]">
						<div class="item-index" :aria-label="`序号 ${index + 1}`">{{ index + 1 }}</div>
						<div class="item-main">
							<div class="ship-section">{{ item.ch }}</div>
							<div class="ship-section">{{ item.fd }}</div>
						</div>
						<div class="item-main">
							<div class="ship-section">{{ item.workArea }}</div>
							<div class="ship-section">{{ item.team || '-' }}</div>
						</div>
						<div class="delay-section">
							<div class="delay-days">{{ item.delay }}天</div>
							<div class="delay-type">{{ getDelayType(item.delay) }}</div>
						</div>
					</div>

					<!-- 为了实现无缝滚动，只有在需要滚动时才复制一份数据 -->
					<template v-if="shouldShowScrollIndicator">
						<div v-for="(item, index) in items || []" :key="`${type}-copy-${index}`" class="delay-item" :class="[getDelayClass(item.delay), { 'copy-item': index === 0 }]">
							<div class="item-index" :aria-label="`序号 ${index + 1}`">{{ index + 1 }}</div>
							<div class="item-main">
								<div class="ship-section">{{ item.ch }}</div>
								<div class="ship-section">{{ item.fd }}</div>
							</div>
							<div class="item-main">
								<div class="ship-section">{{ item.workArea }}</div>
								<div class="ship-section">{{ item.team || '-' }}</div>
							</div>
							<div class="delay-section">
								<div class="delay-days">{{ item.delay }}天</div>
								<div class="delay-type">{{ getDelayType(item.delay) }}</div>
							</div>
						</div>
					</template>
				</div>
			</div>
		</div>
	</div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue';

interface Props {
    title: string;
    categoryName: string;
    items: any[];
    type: 'start' | 'end';
    // 如果为 true，则由父组件显式调用 startScrollAnimation 控制启动与延迟
    externalControl?: boolean;
}

const props = defineProps<Props>();
const emit = defineEmits<{
	(event: 'hover-start'): void;
	(event: 'hover-end'): void;
}>();

// 滚动容器引用
const scrollContainerRef = ref<HTMLElement | null>(null);
const scrollContentRef = ref<HTMLElement | null>(null);

// 滚动动画ID
let scrollAnimationId: number | null = null;
// 启动延迟定时器
let delayTimer: number | null = null;

// 启动参数
interface StartOptions {
    reset?: boolean;     // 是否先复位到顶部
    delayMs?: number;    // 启动前暂停毫秒
}

// 是否显示滚动指示器（黄线）
const shouldShowScrollIndicator = ref(false);

// 延期等级样式
const getDelayClass = (delay: number) => {
	if (delay <= 3) return 'light';
	if (delay <= 7) return 'medium';
	return 'severe';
};

// 延期类型文字
const getDelayType = (delay: number) => {
	if (delay <= 3) return '轻微';
	if (delay <= 7) return '中等';
	return '严重';
};

// 启动滚动动画
const startScrollAnimation = (options?: StartOptions) => {
    stopScrollAnimation();
    if (delayTimer) {
        clearTimeout(delayTimer);
        delayTimer = null;
    }

    if (scrollContentRef.value) {
        const prevCleanup = (scrollContentRef.value as any).cleanup;
        if (typeof prevCleanup == 'function') {
            try { prevCleanup(); } catch {}
        }
        startScrollForContainer(scrollContentRef.value, options);
    }
};

// 停止滚动动画
const stopScrollAnimation = () => {
	if (scrollAnimationId) {
		cancelAnimationFrame(scrollAnimationId);
		scrollAnimationId = null;
	}
};

// 为容器启动滚动
const startScrollForContainer = (scrollContent: HTMLElement, options?: StartOptions) => {
    const itemHeight = 70; // 每项的实际高度（根据CSS中的min-height调整）
	
	// 计算实际数据项数量：如果有复制的数据则减半，否则就是全部
	const totalChildren = scrollContent.children.length;
	const itemsCount = shouldShowScrollIndicator.value ? totalChildren / 2 : totalChildren;
	const totalHeight = itemHeight * itemsCount;
	
	// 获取容器高度，但要限制在合理范围内
	const rawContainerHeight = scrollContainerRef.value?.clientHeight || 0;
	// 延期看板的实际可用高度应该在400-800px范围内，如果超出说明计算有误
	const containerHeight = rawContainerHeight > 1000 ? 600 : rawContainerHeight;
	const visibleItemsCount = Math.floor(containerHeight / itemHeight);
	
	// 调试信息
	console.log(`滚动判断 - 项目数: ${itemsCount}, 原始容器高度: ${rawContainerHeight}, 修正后容器高度: ${containerHeight}, 可见项数: ${visibleItemsCount}`);
	
	// 无论是否滚动，先将位置复位到顶部，确保翻页后从第一条开始
    scrollContent.style.transform = 'translateY(0)';

    // 滚动判断逻辑：数据项数 > 8 则滚动，≤ 8 则不滚动
	if (itemsCount <= 8) {
		console.log(`数据项数 ${itemsCount} ≤ 8，不启动滚动`);
		shouldShowScrollIndicator.value = false;
		return;
	}
	
	console.log(`数据项数 ${itemsCount} > 8，启动滚动动画`);
	shouldShowScrollIndicator.value = true;

    let scrollPosition = 0; // 当前滚动位移（px），与transform保持一致
    let lastTime = 0;
    const scrollSpeed = 20; // 每秒滚动像素数
    let isPaused = false;

    const shouldReset = options?.reset === true;
    const delayMs = Math.max(options?.delayMs || 0, 0);

    // 如需复位，立即将位置复位到顶部
    if (shouldReset) {
        scrollPosition = 0;
        lastTime = 0;
        scrollContent.style.transform = 'translateY(0)';
    }

	const smoothScroll = (currentTime: number) => {
		if (isPaused) {
			scrollAnimationId = requestAnimationFrame(smoothScroll);
			return;
		}

		if (!lastTime) lastTime = currentTime;
		const deltaTime = currentTime - lastTime;

		// 根据时间差计算滚动距离，确保速度一致
		if (deltaTime >= 16) {
			// 约60fps
			scrollPosition += (scrollSpeed * deltaTime) / 1000;

			// 无缝循环 - 确保滚动不会超出数据范围
			if (scrollPosition >= totalHeight) {
				scrollPosition = scrollPosition - totalHeight;
			}

			// 使用transform替代scrollTop，避免抖动
			// 确保滚动位置不会导致内容被遮挡
			scrollContent.style.transform = `translateY(-${Math.min(scrollPosition, totalHeight - 70)}px)`;
			lastTime = currentTime;
		}

		scrollAnimationId = requestAnimationFrame(smoothScroll);
	};

    // 如果当前鼠标已经悬停，初始即为暂停
    const container = scrollContainerRef.value;
    const initiallyHovered = scrollContent.matches(':hover') || container?.matches?.(':hover');
    if (initiallyHovered) {
        isPaused = true;
    }

    // 如果设置了启动延迟，则先暂停，延迟结束再开始滚动
    if (delayMs > 0) {
        isPaused = true;
        delayTimer = window.setTimeout(() => {
            isPaused = false;
            lastTime = 0; // 重置时间，避免延迟后第一帧跳跃
        }, delayMs);
    }

    // 启动滚动动画
    scrollAnimationId = requestAnimationFrame(smoothScroll);

	// 鼠标悬停控制
	const handleMouseEnter = () => {
		isPaused = true;
		emit('hover-start');
	};

	const handleMouseLeave = () => {
		isPaused = false;
		lastTime = 0; // 重置时间，避免暂停后的跳跃
		emit('hover-end');
	};

	scrollContent.addEventListener('mouseenter', handleMouseEnter);
	scrollContent.addEventListener('mouseleave', handleMouseLeave);

	// 鼠标滚轮手动滚动查看当前内容（暂停动画，不触发翻页）
	const handleWheel = (e: WheelEvent) => {
		if (!shouldShowScrollIndicator.value) return; // 数据较少时不需要滚动
		// 手动滚动时保持暂停
		isPaused = true;
		// 阻止默认滚动，避免影响页面
		e.preventDefault();
		// 根据滚轮方向调整位移（deltaY>0 向下，反之向上）
		const delta = e.deltaY;
		scrollPosition += delta;
		// 无缝循环，允许双向滚动
		if (scrollPosition < 0) {
			scrollPosition = (scrollPosition % totalHeight + totalHeight) % totalHeight;
		}
		if (scrollPosition >= totalHeight) {
			scrollPosition = scrollPosition % totalHeight;
		}
		// 应用位移
		scrollContent.style.transform = `translateY(-${Math.min(scrollPosition, totalHeight - 70)}px)`;
	};

	// 监听内容区与容器的滚轮（两处都监听更稳妥）
    scrollContent.addEventListener('wheel', handleWheel, { passive: false });
    container?.addEventListener('wheel', handleWheel, { passive: false });

	// 保存清理函数
    (scrollContent as any).cleanup = () => {
        if (scrollAnimationId) {
            cancelAnimationFrame(scrollAnimationId);
            scrollAnimationId = null;
        }
        if (delayTimer) {
            clearTimeout(delayTimer);
            delayTimer = null;
        }
        scrollContent.removeEventListener('mouseenter', handleMouseEnter);
        scrollContent.removeEventListener('mouseleave', handleMouseLeave);
        scrollContent.removeEventListener('wheel', handleWheel as any);
        container?.removeEventListener('wheel', handleWheel as any);
    };
};

// 监听数据变化，重新启动滚动
watch(
    () => props.items,
    () => {
        if (props.externalControl) return; // 由父组件控制时不自动启动
        nextTick(() => {
            startScrollAnimation({ reset: true });
        });
    },
    { deep: true }
);

// 暴露方法给父组件
defineExpose({
	startScrollAnimation,
	stopScrollAnimation,
});

onMounted(() => {
    if (props.externalControl) return;
    nextTick(() => {
        startScrollAnimation({ reset: true });
    });
});

onUnmounted(() => {
	stopScrollAnimation();

	// 清理滚动动画
	if (scrollContentRef.value && (scrollContentRef.value as any).cleanup) {
		(scrollContentRef.value as any).cleanup();
	}
});
</script>

<style lang="scss" scoped>
.delay-section {
	flex: 1;
	display: flex;
	flex-direction: column;
	min-width: 0;

	.section-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 15px;
		padding: 0 5px;

		h2 {
			color: white;
			font-size: 20px;
			font-weight: bold;
			margin: 0;
			text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
		}

		.category-name {
			color: #ffd700;
			font-size: 16px;
			font-weight: bold;
			background: rgba(255, 215, 0, 0.2);
			padding: 4px 12px;
			border-radius: 20px;
			border: 1px solid rgba(255, 215, 0, 0.3);
			text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
		}

		.section-count {
			color: rgba(255, 255, 255, 0.9);
			font-size: 14px;
			background: rgba(255, 255, 255, 0.2);
			padding: 4px 12px;
			border-radius: 20px;
			font-weight: 600;
		}
	}

	.category-content {
		flex: 1;
		background: rgba(255, 255, 255, 0.1);
		backdrop-filter: blur(10px);
		border-radius: 12px;
		border: 1px solid rgba(255, 255, 255, 0.2);
		overflow: hidden;

		.scroll-container {
			height: 100%;
			overflow: hidden;
			position: relative;

			.scroll-content {
				display: flex;
				flex-direction: column;
				will-change: transform;
				transform: translateY(0);
				transition: none;
			}
		}
	}

	.delay-item {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 12px 15px;
		border-bottom: 1px solid rgba(255, 255, 255, 0.1);
		transition: all 0.3s ease;
		min-height: 70px;

		.item-index {
			flex: 0 0 36px;
			height: 28px;
			line-height: 28px;
			text-align: center;
			border-radius: 14px;
			margin-right: 10px;
			font-weight: 700;
			color: #1e3c72;
			background: #ffd700;
			box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
		}

		&:hover {
			background: rgba(255, 255, 255, 0.1);
		}

		&.light {
			border-left: 4px solid #e6a23c;
		}

		&.medium {
			border-left: 4px solid #f56c6c;
		}

		&.severe {
			border-left: 4px solid #909399;
		}

		/* 滚动数据第一项的黄线标识 */
		&.first-item {
			position: relative;
			&::before {
				content: '';
				position: absolute;
				top: -1px;
				left: 0;
				right: 0;
				height: 3px;
				background: linear-gradient(90deg, #ffd700 0%, #ffeb3b 50%, #ffd700 100%);
				box-shadow: 0 0 6px rgba(255, 215, 0, 0.6);
				z-index: 2;
			}
		}

		/* 复制数据第一项的黄线标识 */
		&.copy-item {
			position: relative;
			&::before {
				content: '';
				position: absolute;
				top: -1px;
				left: 0;
				right: 0;
				height: 3px;
				background: linear-gradient(90deg, #ffd700 0%, #ff8f00 50%, #ffd700 100%);
				box-shadow: 0 0 8px rgba(255, 143, 0, 0.8);
				z-index: 2;
			}
		}

		.item-main {
			flex: 1;
			display: flex;
			flex-direction: column;
			gap: 4px;

			.ship-section {
				color: white;
				font-weight: bold;
				font-size: 14px;
			}
		}

		.delay-section {
			display: flex;
			flex-direction: column;
			align-items: center;
			gap: 4px;

			.delay-days {
				color: white;
				font-weight: bold;
				font-size: 16px;
			}

			.delay-type {
				color: rgba(255, 255, 255, 0.7);
				font-size: 11px;
				padding: 2px 6px;
				border-radius: 6px;
				background: rgba(255, 255, 255, 0.1);
			}
		}
	}
}

@media (max-width: 768px) {
	.delay-section {
		.section-header {
			h2 {
				font-size: 18px;
			}

			.category-name {
				font-size: 14px;
				padding: 3px 10px;
			}

			.section-count {
				font-size: 12px;
				padding: 3px 10px;
			}
		}

		.delay-item {
			padding: 10px 12px;
			min-height: 60px;

			.item-main {
				.ship-section {
					font-size: 13px;
				}
			}

			.delay-section {
				.delay-days {
					font-size: 14px;
				}
			}
		}
	}
}
</style>
